#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <string.h>

// 使用signal代替sigaction设置信号处理函数
static void handle_SIGPIPE(int sig) {
    printf("Child received SIGPIPE signal.\n");
    _exit(EXIT_FAILURE);
}

int main() {
    // 创建匿名管道
    int pipefd[2];
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    // 父进程fork出子进程
    pid_t child_pid = fork();
    if (child_pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (child_pid == 0) { // 子进程
        close(pipefd[0]); // 关闭读端

        // 设置SIGPIPE信号处理函数
        if (signal(SIGPIPE, handle_SIGPIPE) == SIG_ERR) {
            perror("signal");
            exit(EXIT_FAILURE);
        }

        // 尝试不断写入数据
        for (;;) {
            write(pipefd[1], "data", 4);
        }
    } else { // 父进程
        close(pipefd[1]); // 关闭写端

        // 关闭读端管道文件描述符
        close(pipefd[0]);

        // 等待子进程结束
        int status;
        while (waitpid(child_pid, &status, 0) != child_pid) {}

        // 检查子进程退出状态
        if (WIFEXITED(status)) {
            printf("Child exited normally with status %d.\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            if (WTERMSIG(status) == SIGPIPE) {
                printf("Child terminated by SIGPIPE signal.\n");
            } else {
                printf("Child terminated by signal %d: %s\n", WTERMSIG(status), strsignal(WTERMSIG(status)));
            }
        } else {
            printf("Child terminated abnormally.\n");
        }
    }

    return 0;
}